package tms.model;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Map;

import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class Account{

    public static final String TABLE_NAME = "Account";
    public static String[] columns = {"FirstName", "LastName", "Email", "PIDnumber", "Address", "Phone", "IsActive", "FFNumber",
            "FFScore", "Password", "Username", "City", "Province", "Country", "PassportNumber",
            "Title", "IssuingCountry", "AccountNumber", "RegistrationDay", "RegistrationMonth", "RegistrationYear",
            "BirthDay", "BirthMonth", "BirthYear" };

    private int id = -1;
    private String firstName = "";
    private String lastName = "";
    private String email = "";
    private String pidNumber = "";
    private String address = "";
    private String phone = "";
    private boolean isActive = false;
    private String ffNumber = "";
    private int ffScore = 0;
    private String password = "";
    private String username = "";
    private String city = "";
    private String province = "";
    private String country = "";
    private String passportNumber = "";
    private String title = "";
    private String issuingCountry = "";
    private String accountNumber = "";

    private int regDay = 1;
    private int regMonth = 1;
    private int regYear = 2013;

    private int bDay = 1;
    private int bMonth = 1;
    private int bYear = 1980;

    static Account createEntityFrom(Map<String, Object> map) {

        Account entity = new Account();

        entity.setId((Integer) map.get("Id".toLowerCase()));
        entity.setFirstName((String) map.get("FirstName".toLowerCase()));
        entity.setLastName((String) map.get("LastName".toLowerCase()));
        entity.setEmail((String) map.get("Email".toLowerCase()));
        entity.setPidNumber((String) map.get("PIDnumber".toLowerCase()));
        entity.setAddress((String) map.get("Address".toLowerCase()));
        entity.setPhone((String) map.get("Phone".toLowerCase()));
        entity.setActive((Integer) map.get("IsActive".toLowerCase()) == 1);
        entity.setFfNumber((String) map.get("FFNumber".toLowerCase()));
        entity.setFfScore((Integer) map.get("FFScore".toLowerCase()));
//      entity.setRegistrationDate(Helper.ParseDate((String) map.get("RegistrationDate".toLowerCase()), DbManager.DATE_FORMAT));
        entity.setPassword((String) map.get("Password".toLowerCase()));
        entity.setUsername((String) map.get("Username".toLowerCase()));
        entity.setCity((String) map.get("City".toLowerCase()));
        entity.setProvince((String) map.get("Province".toLowerCase()));
        entity.setCountry((String) map.get("Country".toLowerCase()));
        entity.setPassportNumber((String) map.get("PassportNumber".toLowerCase()));
        entity.setTitle((String) map.get("Title".toLowerCase()));
//      entity.setBirthDate(Helper.ParseDate((String) map.get("BirthDate".toLowerCase()), DbManager.DATE_FORMAT));
        entity.setIssuingCountry((String) map.get("IssuingCountry".toLowerCase()));
        entity.setAccountNumber((String) map.get("AccountNumber".toLowerCase()));
        entity.setRegDay((Integer) map.get("RegistrationDay".toLowerCase()));
        entity.setRegMonth((Integer) map.get("RegistrationMonth".toLowerCase()));
        entity.setRegYear((Integer) map.get("RegistrationYear".toLowerCase()));
        entity.setbDay((Integer) map.get("BirthDay".toLowerCase()));
        entity.setbMonth((Integer) map.get("BirthMonth".toLowerCase()));
        entity.setbYear((Integer) map.get("BirthYear".toLowerCase()));

        return entity;
    }

    private String[] getValues() {
        return new String[] {"'" + getFirstName() + "'", "'" + getLastName() + "'", "'" + getEmail() + "'",
            "'" + getPidNumber() + "'", "'" + getAddress() + "'", "'" + getPhone() + "'",
            isActive() == true ? "1" : "0", "'" + getFfNumber() + "'", getFfScore() + "", "'" + getPassword() + "'",
            "'" + getUsername() + "'", "'" + getCity() + "'", "'" + getProvince() + "'", "'" + getCountry() + "'",
            "'" + getPassportNumber() + "'", "'" + getTitle() + "'",
            "'" + getIssuingCountry() + "'", "'" + getAccountNumber() + "'", getRegDay() + "", getRegMonth() + "", getRegYear() + "", getbDay() + "", getbMonth() + "", getbYear() + "" };
    }

    public String getFullName() {
        return firstName + " " + lastName;
    }

    /***** Following methods is important, please don't modify them *************/

    /**
     * Updating if obj is an existed object otherwise insert.
     * @param obj
     * @return true if success otherwise false
     */
    public static boolean save(Account obj) {
        assert (obj != null);
        if (obj.getId() > 0) {
            return update(obj);
        } else {
            return insert(obj);
        }
    }

    /**
     * Insert given Account to database.
     * @param obj
     * @return
     */
    private static boolean insert(Account obj) {
        return DbManager.insert(Account.TABLE_NAME, Account.columns, obj.getValues());
    }

    private static boolean update(Account obj) {
        return DbManager.update(Account.TABLE_NAME, Account.columns,
                obj.getValues(), "id = " + obj.getId());
    }

    public static boolean delete(Account obj) {
        return DbManager.delete(Account.TABLE_NAME, Account.TABLE_NAME + ".id = " + obj.getId());
    }

    /**
     * Get the corresponding account to where clause.
     * @param where condition (ex: Username = 'Tony')
     * @return corresponding account or null
     */
    public static Account getFirstDynamic(String where) {
        Map<String, Object> map = DbManager.getFirstDynamic(Account.TABLE_NAME, where);
        return map != null ? Account.createEntityFrom(map) : null;
    }

    /**
     * Get a list of Account corresponding to where clause.
     * @param where condition (ex: Username = 'Tony')
     * @return corresponding list of Account or an empty list
     */
    public static List<Account> getListDynamic(String where) {
        List<Account> lsResult = new ArrayList<Account>();

        List<Map<String, Object>> rs = DbManager.getListDynamic(Account.TABLE_NAME, where);

        for (Map<String, Object> map : rs) {
            lsResult.add(Account.createEntityFrom(map));
        }

        return lsResult;
    }

    /****************************************************************************/

	@XmlElement
    public int getId() {
        return id;
    }

    private void setId(int id) {
        this.id = id;
    }

	@XmlElement
    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

	@XmlElement
    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

	@XmlElement
    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

	@XmlElement
    public String getPidNumber() {
        return pidNumber;
    }

    public void setPidNumber(String pidNumber) {
        this.pidNumber = pidNumber;
    }

	@XmlElement
    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

	@XmlElement
    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

	@XmlElement
    public boolean isActive() {
        return isActive;
    }

    public void setActive(boolean isActive) {
        this.isActive = isActive;
    }

	@XmlElement
    public String getFfNumber() {
        return ffNumber;
    }

    public void setFfNumber(String ffNumber) {
        this.ffNumber = ffNumber;
    }

	@XmlElement
    public int getFfScore() {
        return ffScore;
    }

    public void setFfScore(int ffScore) {
        this.ffScore = ffScore;
    }

    /**
     * @return Registration date without time
     */
    public Date getRegistrationDate() {
        Calendar c = Calendar.getInstance();
        c.set(getRegYear(), getRegMonth() - 1, getRegDay());
        return c.getTime();
    }

    public void setRegistrationDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        setRegDay(c.get(Calendar.DAY_OF_MONTH));
        setRegMonth(c.get(Calendar.MONTH) + 1);
        setRegYear(c.get(Calendar.YEAR));
    }

	@XmlElement
    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

	@XmlElement
    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

	@XmlElement
    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

	@XmlElement
    public String getProvince() {
        return province;
    }

    public void setProvince(String province) {
        this.province = province;
    }

	@XmlElement
    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

	@XmlElement
    public String getPassportNumber() {
        return passportNumber;
    }

    public void setPassportNumber(String passportNumber) {
        this.passportNumber = passportNumber;
    }

	@XmlElement
    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * @return Birth date without time
     */
    public Date getBirthDate() {
        Calendar c = Calendar.getInstance();
        c.set(getbYear(), getbMonth() - 1, getbDay());
        return c.getTime();
    }

    public void setBirthDate(Date date) {
        Calendar c = Calendar.getInstance();
        c.setTime(date);
        setbDay(c.get(Calendar.DAY_OF_MONTH));
        setbMonth(c.get(Calendar.MONTH) + 1);
        setbYear(c.get(Calendar.YEAR));
    }

    @XmlElement
    public String getIssuingCountry() {
        return issuingCountry;
    }

    public void setIssuingCountry(String issuingCountry) {
        this.issuingCountry = issuingCountry;
    }

    @XmlElement
    public String getAccountNumber() {
        return accountNumber;
    }

    public void setAccountNumber(String accountNumber) {
        this.accountNumber = accountNumber;
    }

    @XmlElement
    public int getRegDay() {
		return regDay;
	}

	private void setRegDay(int regDay) {
		this.regDay = regDay;
	}

	@XmlElement
	public int getRegMonth() {
		return regMonth;
	}

	private void setRegMonth(int regMonth) {
		this.regMonth = regMonth;
	}

	@XmlElement
	public int getRegYear() {
		return regYear;
	}

	private void setRegYear(int regYear) {
		this.regYear = regYear;
	}

	@XmlElement
	public int getbDay() {
		return bDay;
	}

	private void setbDay(int bDay) {
		this.bDay = bDay;
	}

	@XmlElement
	public int getbMonth() {
		return bMonth;
	}

	private void setbMonth(int bMonth) {
		this.bMonth = bMonth;
	}

	@XmlElement
	public int getbYear() {
		return bYear;
	}

	private void setbYear(int bYear) {
		this.bYear = bYear;
	}

}
